package com.hjy.interceptor;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.hjy.annotation.HasAuth;
import com.hjy.annotation.HasRole;
import com.hjy.pojo.R;
import com.hjy.pojo.UserDetail;
import com.hjy.properties.HjySecurityProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class AuthorizeInterceptor implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;
    private HjySecurityProperties hjySecurityProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod = null;
        try {
            handlerMethod = (HandlerMethod) handler;
        }catch (Exception e){

        }
        /* 存储相关的权限 */
        List<String> authList = new ArrayList<>();
        List<String> roleList = new ArrayList<>();
        try {
            // 首先获取挂接在 controller 上的注解
            HasAuth hasAuthClass = handlerMethod.getBean().getClass().getAnnotation(HasAuth.class);
            if (hasAuthClass != null) {
                authList.addAll(Arrays.asList(hasAuthClass.value()));
            }
            HasRole hasRoleClass = handlerMethod.getBean().getClass().getAnnotation(HasRole.class);
            if (hasRoleClass != null) {
                roleList.addAll(Arrays.asList(hasRoleClass.value()));
            }

            // 然后获取方法身上的权限
            HasAuth hasAuthMethod = handlerMethod.getMethodAnnotation(HasAuth.class);
            if (hasAuthMethod != null) {
                authList.addAll(Arrays.asList(hasAuthMethod.value()));
            }
            HasRole hasRoleMethod = handlerMethod.getMethodAnnotation(HasRole.class);
            if (hasRoleMethod != null) {
                roleList.addAll(Arrays.asList(hasRoleMethod.value()));
            }
        }catch (Exception e) {

        }

        // 去重
        authList = authList.stream().distinct().collect(Collectors.toList());
        roleList = roleList.stream().distinct().collect(Collectors.toList());

        // 如果都是空的, 说明没有权限认证, 直接放行
        if (authList.isEmpty() && roleList.isEmpty()) {
            return true;
        }

        /* 获取当前用户的权限 */
        // 获取token
        String token = request.getHeader(hjySecurityProperties.getHeaderName());
        // 如果没有携带 token , 就返回登录页
        if (StrUtil.isBlank(token)) {
            // 返回登录页面
            response.sendRedirect(hjySecurityProperties.getLoginPageUrl());
        }
        String s = stringRedisTemplate.opsForValue().get(hjySecurityProperties.getRedisPrefix() + token);
        UserDetail userDetail = JSONUtil.toBean(s, UserDetail.class);
        // 找到与类中定义权限相同的
        Collection<String> authListIntersection = CollUtil.intersection(authList, userDetail.getAuths());
        Collection<String> roleListIntersection = CollUtil.intersection(roleList, userDetail.getRoles());

        // 如果都没有交集, 就返回false
        if (authListIntersection.isEmpty() && roleListIntersection.isEmpty()) {
            response.setContentType("application/json;charset=utf-8");
            R error = R.error();
            error.setMessage("对不起, 你没有访问该接口的权限");
            response.getWriter().write(JSONUtil.toJsonStr(error));
            return false;
        }
        return true;
    }
}
